package cn.wei.sdd.core.service.impl;

import cn.wei.common.exception.Assert;
import cn.wei.common.result.ResponseEnum;
import cn.wei.sdd.core.enums.*;
import cn.wei.sdd.core.mapper.*;
import cn.wei.sdd.core.pojo.entity.*;
import cn.wei.sdd.core.pojo.query.OrdersQuery;
import cn.wei.sdd.core.pojo.vo.*;
import cn.wei.sdd.core.service.DictService;
import cn.wei.sdd.core.service.OrderService;
import cn.wei.sdd.core.utils.CheckCodeUtil;
import cn.wei.sdd.core.utils.MyEncryptUtils;
import cn.wei.sdd.core.utils.NoUtils;
import cn.wei.sdd.rabbitutils.service.MQService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 回收订单表 服务实现类
 * </p>
 *
 * @author Wei
 * @since 2021-10-25
 */
@Slf4j
@Service
public class OrderServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrderService {

    @Resource
    private DictService dictService;

    @Resource
    private OrderItemMapper orderItemMapper;

    @Resource
    private GrabOrderRecordMapper grabOrderRecordMapper;

    @Resource
    private UserAccountMapper userAccountMapper;


    @Resource
    private UserMapper userMapper;

    @Resource
    private TransFlowMapper transFlowMapper;

    @Resource
    private CheckRecordMapper checkRecordMapper;

    @Resource
    private MQService mqService;

    @Resource
    OrdersMapper ordersMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reservationOrder(PlaceOrdersVO placeOrdersVO, Long userId) {
        Orders orders = new Orders();
        orders.setUserId(userId);
        BeanUtils.copyProperties(placeOrdersVO, orders);
        orders.setStatus(OrderStatusEnum.Wait_Order.getStatus());
        orders.setOrderNo(NoUtils.getOrdersNo());
        baseMapper.insert(orders);

        List<OrderItemVO> orderItemVO = placeOrdersVO.getOrderItemVO();
        BigDecimal totalPrice = new BigDecimal(0.00);
        for (OrderItemVO itemVO : orderItemVO) {
            OrderItem orderItem = new OrderItem();
            BigDecimal price = dictService.getPriceById(itemVO.getDictId());
            BeanUtils.copyProperties(itemVO, orderItem);
            orderItem.setOrderId(orders.getId());
            orderItem.setPrice(price);

            orderItemMapper.insert(orderItem);
            //相乘
            price = price.multiply(BigDecimal.valueOf(itemVO.getWeight()));

            //累加
            totalPrice= totalPrice.add(price) ;

        }

        //计算订单总价
        Orders orders1 = new Orders();
        orders1.setId(orders.getId());
        orders1.setTotalPrice(totalPrice);
        baseMapper.updateById(orders1);

        //计算预约时间
        String scheduledTime = placeOrdersVO.getScheduledTime();//预约时间
        String appointmentTime = scheduledTime.substring(0, scheduledTime.indexOf("~"));//预约时间
        System.out.println("预约时间："+appointmentTime);


        Date dateFromDB = new Date();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String beginTime = null;
        try {
            beginTime = df.format(dateFromDB);
        } catch (Exception e) {
            e.printStackTrace();
        }
        long min = findMin(beginTime,appointmentTime);
        log.info("预约联系人人：{}，预约订单到期还有：{}分钟",orders.getUserName(),min);

        Integer dateTime = Math.toIntExact(min * 60 * 1000);


        mqService.sendOrder(orders.getOrderNo(),dateTime);


    }
    /**
     * 计算两个时间相差分钟数
     * @param beginTime
     * @param endTime
     * @return
     */
    public long findMin(String beginTime, String endTime){
        SimpleDateFormat dfs = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        try {
            Date begin = dfs.parse(beginTime);
            Date end = dfs.parse(endTime);
            long between = (end.getTime() - begin.getTime())/1000;
            long min = between/60;
            return min;
        }catch (Exception e){
            e.printStackTrace();
        }
        return 0;
    }

    @Override
    public List<UserOrdersVO> getOrdersByUserId(Long userId, Integer status) {
        QueryWrapper<Orders> ordersQueryWrapper = new QueryWrapper<>();
        ordersQueryWrapper.eq("user_id",userId);
        if (status==1){
            //进行中订单：Wait_Order待接单，Waiting_For_The_Door等待上门
            // where user_id = 1 and (`status` = 0 or `status` = 1)
            ordersQueryWrapper
                .and(
                        Wrapper ->Wrapper
                                .eq("status",OrderStatusEnum.Wait_Order.getStatus())
                                .or()
                                .eq("status",OrderStatusEnum.Waiting_For_The_Door.getStatus())
                ).orderByDesc("id");
        }else{
            ordersQueryWrapper
                    .and( Wrapper ->Wrapper
                            .eq("status",OrderStatusEnum.Cancel_Order.getStatus())
                            .or()
                            .eq("status",OrderStatusEnum.overTime.getStatus())
                            .or()
                            .eq("status",OrderStatusEnum.Finish.getStatus())
                    ).orderByDesc("id");

        }
        //查询该 UserId 下的所有订单
        List<Orders> orders = baseMapper.selectList(ordersQueryWrapper);

        //结果是否为空
        Assert.isTrue(!orders.isEmpty(), ResponseEnum.No_Data);

        return this.getOrdersVOListByOrdersList(orders);

    }

    @Override
    public List<UserOrdersVO> getWaitOrders() {

        QueryWrapper<Orders> ordersQueryWrapper = new QueryWrapper<>();
        ordersQueryWrapper.eq("status",OrderStatusEnum.Wait_Order.getStatus());
        List<Orders> orders = baseMapper.selectList(ordersQueryWrapper);
        Assert.isTrue(!orders.isEmpty(),ResponseEnum.No_Data);
        return this.getOrdersVOListByOrdersList(orders);
    }

    @Override
    public List<UserOrdersVO> getOrdersByRecyclerId(Long recyclerId, Long recyclerStatus) {
        QueryWrapper<Orders> ordersQueryWrapper = new QueryWrapper<>();
        ordersQueryWrapper
                .eq("recycler_id",recyclerId)
                .eq("recycler_status",recyclerStatus);

        List<Orders> orders = baseMapper.selectList(ordersQueryWrapper);
        Assert.isTrue(!orders.isEmpty(),ResponseEnum.No_Data);
        return this.getOrdersVOListByOrdersList(orders);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void grabOrder(String orderNo, Long recyclerId, String recyclerName) {
        QueryWrapper<Orders> ordersQueryWrapper = new QueryWrapper<>();
        //查询是否已经被抢单了
        ordersQueryWrapper.eq("order_no",orderNo)
                .isNull("recycler_id");

        Integer count = baseMapper.selectCount(ordersQueryWrapper);
        //如果不为真，则抛出异常：哎呀手速慢了
        Assert.isTrue(count>0,ResponseEnum.GRAB_AFTER);

        //更改订单状态
        Orders orders = new Orders();
        orders.setStatus(OrderStatusEnum.Waiting_For_The_Door.getStatus());
        orders.setRecyclerStatus(HandleStatusEnum.WAIT_ORDER.getStatus());
        orders.setRecyclerId(recyclerId);
        orders.setRecyclerName(recyclerName);
        QueryWrapper<Orders> updateOrdersQueryWrapper = new QueryWrapper<>();
        updateOrdersQueryWrapper.eq("order_no",orderNo);
        baseMapper.update(orders,updateOrdersQueryWrapper);

        //抢单记录
        GrabOrderRecord record = new GrabOrderRecord();
        record.setOrderNo(orderNo);
        record.setRecyclerId(recyclerId);
        record.setRecyclerName(recyclerName);
        grabOrderRecordMapper.insert(record);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void confirmOrders(ConfirmOrdersVO confirmOrdersVO, Long userId) {
        System.out.println("cash:"+confirmOrdersVO.getCashPayment());

        //获取订单项
        List<OrderItemVO> orderItemVO = confirmOrdersVO.getOrderItemVO();

        QueryWrapper<Orders> ordersQueryWrapper = new QueryWrapper<>();
        //查询订单
        ordersQueryWrapper.eq("order_no",confirmOrdersVO.getOrderNo());
        Orders orders = baseMapper.selectOne(ordersQueryWrapper);
        Orders updateOrders = new Orders();
        //更新订单
        updateOrders.setId(orders.getId());
        updateOrders.setRecyclerStatus(HandleStatusEnum.PACK_CHECK.getStatus());
        updateOrders.setStatus(OrderStatusEnum.Finish.getStatus());
        updateOrders.setTotalPrice(confirmOrdersVO.getTotalPrice());
        updateOrders.setCashPayment(confirmOrdersVO.getCashPayment());
        baseMapper.updateById(updateOrders);


        //把订单添加到验收表
        CheckRecord checkRecord = new CheckRecord();
        checkRecord.setOrderId(orders.getId());
        checkRecord.setOrderNo(orders.getOrderNo());
        checkRecord.setRecyclerId(userId);
        try {
            checkRecord.setCheckCode(MyEncryptUtils.AESencrypt(CheckCodeUtil.randomCheckCode()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        checkRecord.setStatus(CheckStatusEnum.NOT_CHECK.getStatus());
        checkRecordMapper.insert(checkRecord);


        //获取用户详情
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("id",orders.getUserId())
                .eq("user_type",User.USER);
        User user = userMapper.selectOne(userQueryWrapper);


        //添加流水
        TransFlow transFlow = new TransFlow();
        transFlow.setUserType(User.USER);
        transFlow.setUserId(orders.getUserId());
        transFlow.setTransNo(NoUtils.getTransNo());
        transFlow.setUserName(user.getUserName());
        transFlow.setTransType(TransStatusEnum.INCOME.getStatus());
        transFlow.setTransTypeName(TransStatusEnum.INCOME.getMsg());
        transFlow.setTransAmount(confirmOrdersVO.getTotalPrice());


        QueryWrapper<UserAccount> userAccountQueryWrapper = new QueryWrapper<>();
        userAccountQueryWrapper.eq("user_type",User.USER)
                .eq("user_id",orders.getUserId());
        //更新用户账户
        UserAccount account = userAccountMapper.selectOne(userAccountQueryWrapper);

        UserAccount userAccount = new UserAccount();

        userAccount.setId(account.getId());
        //添加累计收益
        BigDecimal totalShouyi = account.getTotalShouyi();
        totalShouyi = totalShouyi.add(confirmOrdersVO.getTotalPrice());
        userAccount.setTotalShouyi(totalShouyi);

        //        是否现金支付,如果是
        if (confirmOrdersVO.getCashPayment()== CashPaymentStatusEnum.IS_cashPayment.getStatus()){
            transFlow.setMemo(CashPaymentStatusEnum.IS_cashPayment.getMsg()+"订单号："+confirmOrdersVO.getOrderNo());

        }else{

            //获取账户金额
            BigDecimal amount = account.getAmount();
            //账户金额+订单金额
            amount = amount.add(confirmOrdersVO.getTotalPrice());
            userAccount.setAmount(amount);

            //添加流水
            transFlow.setMemo("订单收入，订单号："+confirmOrdersVO.getOrderNo());

        }
        userAccountMapper.updateById(userAccount);
        transFlowMapper.insert(transFlow);




        QueryWrapper<OrderItem> orderItemQueryWrapper = new QueryWrapper<>();
        //删除预约时的订单项
        orderItemQueryWrapper.eq("order_id",orders.getId());
        orderItemMapper.delete(orderItemQueryWrapper);
        //从新添加确认的订单项
        BigDecimal weight = new BigDecimal(0.0);
        for (OrderItemVO itemVO : orderItemVO) {
            OrderItem orderItem = new OrderItem();
            weight = weight.add(BigDecimal.valueOf(itemVO.getWeight()));
            orderItem.setOrderId(orders.getId());
            BeanUtils.copyProperties(itemVO,orderItem);
            orderItemMapper.insert(orderItem);
        }
        System.out.println("weight:"+weight);

        //更新用户信息
        //累计回收次数
        Integer number = user.getRecoveryNumber();
        //累计回收重量
        double totalWeight = weight.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue()+user.getRecoveryWeight();
        UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
        userUpdateWrapper
                .eq("id",user.getId())
                .set("recovery_number",number+1)
                .set("recovery_weight",totalWeight);
        userMapper.update(null,userUpdateWrapper);

    }

    public List<UserOrdersVO> getOrdersVOListByOrdersList(List<Orders> orders){
        //最终返回给前端的数据对象
        List<UserOrdersVO> userOrdersVOList = new ArrayList<>();

        for (Orders order : orders) {
            //每个订单包含的商品
            List<OrderItemVO> orderItemVOList = new ArrayList<>();
            //设置用户的每一条订单数据
            UserOrdersVO userOrdersVO = new UserOrdersVO();
            //将查询出来的数据对应字段赋值给 userOrdersVO
            BeanUtils.copyProperties(order, userOrdersVO);
            //设置订单状态名
            if (order.getStatus()==OrderStatusEnum.Cancel_Order.getStatus()){
                userOrdersVO.setStatusName(OrderStatusEnum.getMsgByStatus(order.getStatus()));
            }
            else if (order.getStatus()==OrderStatusEnum.Wait_Order.getStatus()){
                userOrdersVO.setStatusName(OrderStatusEnum.getMsgByStatus(order.getStatus()));
            }else if (order.getStatus()==OrderStatusEnum.Waiting_For_The_Door.getStatus()){
                userOrdersVO.setStatusName(OrderStatusEnum.getMsgByStatus(order.getStatus()));
            }
            else if (order.getStatus()==OrderStatusEnum.Finish.getStatus()){
                userOrdersVO.setStatusName(OrderStatusEnum.getMsgByStatus(order.getStatus()));
            }
            else if (order.getStatus()==OrderStatusEnum.overTime.getStatus()){
                userOrdersVO.setStatusName(OrderStatusEnum.getMsgByStatus(order.getStatus()));
            }

            if (order.getRecyclerStatus()==HandleStatusEnum.WAIT_ORDER.getStatus()){
                userOrdersVO.setRecyclerStatus(HandleStatusEnum.getMsgByStatus(order.getRecyclerStatus()));
            }
//            else  if (order.getRecyclerStatus()==HandleStatusEnum.WAIT_PACK.getStatus()){
//                userOrdersVO.setRecyclerStatus(HandleStatusEnum.getMsgByStatus(order.getRecyclerStatus()));
//            }
            else  if (order.getRecyclerStatus()==HandleStatusEnum.PACK_CHECK.getStatus()){
                userOrdersVO.setRecyclerStatus(HandleStatusEnum.getMsgByStatus(order.getRecyclerStatus()));
            }
            else  if (order.getRecyclerStatus()==HandleStatusEnum.FINISH_ORDER.getStatus()){
                userOrdersVO.setRecyclerStatus(HandleStatusEnum.getMsgByStatus(order.getRecyclerStatus()));
            }



            //根据orderId 查询 当前订单的商品项
            List<OrderItem> itemList = orderItemMapper.getOrderItemByOrderId(order.getId());

            for (OrderItem orderItem : itemList) {
                //设置每一条商品项数据
                OrderItemVO orderItemVO = new OrderItemVO();

                BeanUtils.copyProperties(orderItem, orderItemVO);
                orderItemVOList.add(orderItemVO);
            }
            userOrdersVO.setOrderItemVO(orderItemVOList);
            userOrdersVOList.add(userOrdersVO);

        }

        return userOrdersVOList;
    }

    @Override
    public BigDecimal getTotalPriceByOrdersId(Long id){

        BigDecimal totalPrice = new BigDecimal(0.0);

        //获取该订单下的所有商品项
        List<OrderItem> itemList = orderItemMapper.getOrderItemByOrderId(id);

        for (OrderItem orderItem : itemList) {
            //单价
            BigDecimal price = orderItem.getPrice();

            //相乘
            price = price.multiply(BigDecimal.valueOf(orderItem.getWeight()));

            //累加
            totalPrice= totalPrice.add(price) ;
        }
        return totalPrice;
    }

    @Override
    public IPage<Orders> listPage(Page<Orders> pageParam, OrdersQuery ordersQuery) {
        if (ordersQuery==null){
            return baseMapper.selectPage(pageParam,null);
        }
        String mobile = ordersQuery.getMobile();
        String orderNo = ordersQuery.getOrderNo();
        Integer status = ordersQuery.getStatus();
        QueryWrapper<Orders> ordersQueryWrapper = new QueryWrapper<>();
        ordersQueryWrapper
                .eq(mobile!=null&&!mobile.isEmpty(),"mobile",mobile)
                .eq(orderNo!=null&&!orderNo.isEmpty(),"order_no",orderNo)
                .eq(status!=null,"status",status);
        return baseMapper.selectPage(pageParam,ordersQueryWrapper);

    }

    @Override
    public List<OrderStatisticsVO> getOrderStatisticsByDate(String recentTime) {
        return baseMapper.selectOrderStatisticsByDate(recentTime);
    }

    @Override
    public List<OrderStatisticsVO> getRecyclerStatisticsByDate(String recentTime) {
        return baseMapper.selectRecyclerStatisticsByDate(recentTime);
    }

    @Override
    public Orders getOrderByOrderNo(String orderNo) {
        QueryWrapper<Orders> ordersQueryWrapper = new QueryWrapper<>();
        ordersQueryWrapper.eq("order_no",orderNo);
        return ordersMapper.selectOne(ordersQueryWrapper);
    }

    @Override
    public int selectOrderStatusByOrderNo(Long userId, String orderNo) {
        QueryWrapper<Orders> ordersQueryWrapper = new QueryWrapper<>();
        ordersQueryWrapper.eq("user_id",userId).eq("order_no",orderNo).select("status");
        return ordersMapper.selectOne(ordersQueryWrapper).getStatus();
    }

    @Override
    public void OrderCancelByOrderNo(String orderNo) {
        UpdateWrapper<Orders> ordersUpdateWrapper = new UpdateWrapper<>();
        ordersUpdateWrapper.eq("order_no",orderNo)
                .eq("status",OrderStatusEnum.Wait_Order.getStatus())
                .set("status",OrderStatusEnum.Cancel_Order.getStatus());
        ordersMapper.update(null,ordersUpdateWrapper);
    }


}
